home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
eulisp
/
mpfeel.lha
/
MPFeel
/
Plurals
/
eubang.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-15
|
57KB
|
1,933 lines
/*
* Plurals - A SIMD extension to Eulisp
*
* Author: S.C.Merrall
*
* File: eubang.c
*
* Contents:
*
* Description: Plurals are objects allocated from a processor array
* They are like vectors where each element is on a
* seperate processor.
*
* Change History:
*
* Date Name Comment
* -------- ---- -------
* 16:05:91 SCM Created
* 27:01:92 SCM Added support for symbols
* 26:03:92 SCM Removed cm-identify, replaced by cm_put and cm_start
* 09:04:92 SCM Added functions for handling temporary pluralspace in lisp
* 07:06:92 SCM Added xnet move stuff
*
*/
#include <stdio.h>
#include "defs.h"
#include "structs.h"
#include "funcalls.h"
#include "global.h"
#include "error.h"
#include "allocate.h"
#include "modboot.h"
#include "vectors.h" /* To be able to use vectors macros */
#define ARG_4(stack) (*(stack+4))
#ifdef __STDC__
#define EUFUN_5(name, a1, a2, a3, a4, a5) \
LispObject name (LispObject *stackbase) \
{ \
LispObject a1; \
LispObject a2; \
LispObject a3; \
LispObject a4; \
LispObject a5; \
LispObject *stacktop = stackbase+5; \
/*toplabel:*/ \
a1 = ARG_0(stackbase); \
a2 = ARG_1(stackbase); \
a3 = ARG_2(stackbase); \
a4 = ARG_3(stackbase); \
a5 = ARG_4(stackbase);
#else
#define EUFUN_5(name, a1, a2, a3, a4, a5 ) \
LispObject name (stackbase) \
LispObject *stackbase; \
{ \
LispObject a1; \
LispObject a2; \
LispObject a3; \
LispObject a4; \
LispObject a5; \
LispObject *stacktop = stackbase+5; \
/*toplabel:*/ \
a1 = ARG_0(stackbase); \
a2 = ARG_1(stackbase); \
a3 = ARG_2(stackbase); \
a4 = ARG_3(stackbase); \
a5 = ARG_4(stackbase);
#endif
#include "table.h" /* We use a table to keep track of symbols
* referenced by the front end
*/
extern FILE* current_output;
extern LispObject ListOfStrangeThings;
#include "mp_eubang.h"
int call_request_value;
int fe_mp_error;
#define DBG_CALL(name) char *dbg_fname=name
#define CallRequest(alist) (((call_request_value=callRequest alist)==FAIL) ? (copyIn((char *) &mp_error,(char *) &fe_mp_error, sizeof(int)),(int)CallError(stacktop,dbg_fname,allocate_integer(stacktop,fe_mp_error),NONCONTINUABLE)) : call_request_value)
#ifdef XLIGHTS
extern void visualise();
#endif
/*char fe_scratch[MASPAR_CONFIG][SCRATCH_MEMORY_SIZE]; Communication scratch
* space, total area
* equal on both ends.
*/
int maspar_config;
char *fe_scratch;
int fe_data_length; /* for decode and encode */
char *pe_scratch; /* This is the address of the communicatiuon scratch
* space on the back end. Initialised by mp_init in
* INIT_plural.
*/
LispObject reffed_symbols; /* Which symbols have been reffed? */
LispObject fe_symbol_table; /* Table of fe symbols refenced by be */
int next_symbol_key; /* key fe_symbols are stored under */
#define allocate_mp_context(address) \
({int __xxx=address; \
allocate_integer(stacktop,(int) __xxx); })
#define mp_context_address(LObj) ((char *) (intval(LObj)))
#define allocate_mp_plural(offset) \
({int __xxx=offset; \
allocate_integer(stacktop,(int) __xxx); })
#define mp_plural_offset(LObj) (intval(LObj))
/* keep compiler happy */
#define intval_addr(x) \
&(x->INT.value_part)
/*----------------------------------------------------------------------------*
* Function : Fn_mp_make_context
*
* Parameters : LispObject width: Width of the new context
* LispObject height: Hwight of the new context
*
* Description: Creates a new context of size elements
*
* Result : LispObject: New Plural
*---------------------------------------------------------------------------*/
EUFUN_2(Fn_mp_make_context,width,height)
{
DBG_CALL("Error in mp-make-context");
LispObject mp_object;
mp_object = allocate_mp_context( CallRequest((mp_make_context,8,intval(width),intval(height))));
return mp_object;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_make_plural
*
* Parameters : LispObject context: Address of a maspar context for the
* new plural
*
* Description: Allocates a new Plural which has as its context (i.e
* processor set and context stack) context
*
* Result : LispObject: New Plural
*---------------------------------------------------------------------------*/
EUFUN_1( Fn_mp_make_plural, context )
{
DBG_CALL("Error in mp-make-plural");
LispObject mp_object;
mp_object = allocate_mp_plural( CallRequest((mp_make_plural,4,
mp_context_address(context))));
return mp_object;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_print
*
* Parameters : LispObject context: Context and offset of
* LispObject offset: Plural to be printed.
* LispObject width: width of context if appropriate
* LispObject partial: and wether it is partial in x
*
* Description: Prints a plural variable in the usual fashion to the stdout
*
* Result : LispObject plural: offset of the printed plural
*---------------------------------------------------------------------------*/
EUFUN_5( Fn_mp_print, context, offset, width, partial, stream)
{
DBG_CALL("Error in mp-print");
int i, j, w;
int transferred;
int firstline = 1;
char *chars;
int id;
CallRequest((mp_plural, 20, mp_context_address(context),MP_PRINT, 1, 1,
mp_plural_offset(offset)));
transferred = blockIn(pe_scratch,fe_scratch,0,0,MASPAR_XLEN,
MASPAR_YLEN, SCRATCH_MEMORY_SIZE);
if ((stream==NULL)||(stream==nil)) current_output = (StdOut->STREAM).handle;
else current_output = (stream->STREAM).handle;
if (width == nil) {
for (i=0; i<maspar_config; i++) {
chars = fe_scratch + (i * SCRATCH_MEMORY_SIZE);
while (*chars != NULL) {
if (*chars == ((char) 1)) {
++chars;
for (j=0; j< sizeof(int); j++) *(((char *) &id) + j) = *(chars++);
EUCALL_2(Fn_prin,TREF(fe_symbol_table,
allocate_integer( stacktop,id )),stream);
}
else putc(*(chars++),current_output);
}
if (chars != (fe_scratch + (i*SCRATCH_MEMORY_SIZE)))
putc(' ',current_output);
}
}
else {
w = intval(width);
i = 0;
while (i < maspar_config) {
chars = fe_scratch + (i * SCRATCH_MEMORY_SIZE);
if (*chars == NULL) { ++i; continue; }
if ((w == intval(width)) && !firstline) fprintf(current_output,"\n ");
while (*chars != NULL) {
if (*chars == ((char) 1)) {
++chars;
for (j=0; j< sizeof(int); j++) *(((char *) &id) + j) = *(chars++);
EUCALL_2(Fn_prin,TREF(fe_symbol_table,
allocate_integer( stacktop,id )),stream);
}
else putc(*(chars++),current_output);
}
fprintf(current_output," ");
if ((--w) == 0) {
firstline = 0;
w = intval(width);
if (partial != nil) fprintf(current_output,"...");
/* fprintf(current_output,"\n");*/
}
++i;
}
}
current_output = StdOut->STREAM.handle;
return offset;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : encode_object
*
* Parameters : LispObject object: object being encoded
*
* Description: Recursively walks over a lisp object and encodes it into
* fe_scratch, this can then be read by the back end to create
* the object on the array. See mp_eubang.m for a fuller
* description of the encoded format.
*
* Result : int : arb
*---------------------------------------------------------------------------*/
#ifdef __STDC__
int encode (LispObject *stacktop, LispObject object)
#else
int encode (stacktop,object)
LispObject *stacktop;
LispObject object;
#endif
{
int i;
float real;
LispObject new_id;
if (fe_data_length >= (MASPAR_CONFIG*SCRATCH_MEMORY_SIZE)) {
return EXCEEDED_SCRATCH_SPACE;
}
if (is_fixnum(object)) {
fe_scratch[fe_data_length++] = INTEGER;
memcpy(fe_scratch+fe_data_length,
(char *) &(intval(object)), sizeof(int));
fe_data_length = fe_data_length + sizeof(int);
}
else if (is_float(object)) {
fe_scratch[fe_data_length++] = MP_FLOAT;
real = object->FLOAT.fvalue;
memcpy(fe_scratch+fe_data_length,
(char *) &real, sizeof(float));
fe_data_length = fe_data_length + sizeof(float);
}
else if (object == lisptrue) {
fe_scratch[fe_data_length++] = MP_SPECIAL;
fe_scratch[fe_data_length++] = NOT_NIL;
}
else if (is_symbol(object)) {
int unique_symbol_key;
if ((new_id = TREF(reffed_symbols,object)) == nil) {
unique_symbol_key = next_symbol_key; /* Symbol not reffed before, we */
++next_symbol_key; /* need a new unique identifier */
new_id = allocate_integer(stacktop,unique_symbol_key);
TREF_UPDATE(fe_symbol_table,new_id,object);
TREF_UPDATE(reffed_symbols,object,new_id);
}
else unique_symbol_key = (intval(new_id));
fe_scratch[fe_data_length++] = MP_SYMBOL;
memcpy(fe_scratch+fe_data_length,
(char *) &unique_symbol_key, sizeof(char *));
fe_data_length = fe_data_length + sizeof(char *);
}
else if (is_vector(object)) {
fe_scratch[fe_data_length++] = MP_VECTOR;
fe_scratch[fe_data_length++] = object->VECTOR.length;
for (i=0; i<object->VECTOR.length; i++) {
encode(stacktop,vref(object,i));
}
}
else if (is_cons(object)) {
fe_scratch[fe_data_length++] = MP_CONS;
STACK_TMP(object);
encode(stacktop,CAR(object));
UNSTACK_TMP(object);
encode(stacktop,CDR(object));
}
else if (null(object)) {
fe_scratch[fe_data_length++] = MP_SPECIAL;
fe_scratch[fe_data_length++] = NIL;
}
else {
return UNKNOWN_TYPE;
}
return SUCCESS;
}
/*----------------------------------------------------------------------------*
* Function : decode_object
*
* Parameters : char *start: Where the description is located
* int *index: Current position in description buffer;
*
* Description: Builds a lisp structure from a coded description in des_buffer
*
* Result : LispObject: The resulting structure
*---------------------------------------------------------------------------*/
#ifdef __STDC__
LispObject decode_object ( LispObject *stacktop,char *start, int *index )
#else
LispObject decode_object ( stacktop,start, index )
char *start;
int *index;
LispObject *stacktop;
#endif
{
int i;
float real;
int number;
int type;
int size;
int element;
int length = (int) *start;
LispObject decoded_car;
LispObject decoded_cdr;
LispObject result;
char *value_address;
if (*index > length) return nil;
type = (int) start[(*index)++];
switch(type) {
case MP_SPECIAL :
if (start[(*index)++] == NOT_NIL) return lisptrue;
else return nil;
case INTEGER :
value_address = (char *) &number;
for (i=0; i<sizeof(int); i++) {
*(value_address + i) = start[(*index)++];
}
return allocate_integer(stacktop, number );
case MP_FLOAT :
value_address = (char *) ℜ
for (i=0; i<sizeof(int); i++) {
*(value_address + i) = start[(*index)++];
}
return allocate_float( stacktop,real );
case MP_SYMBOL :
value_address = (char *) &number;
for (i=0; i<sizeof(int); i++) *(value_address + i) = start[(*index)++];
return TREF(fe_symbol_table,allocate_integer(stacktop,number));
case MP_CONS :
decoded_car = decode_object(stacktop,start,index);
STACK_TMP(decoded_car);
decoded_cdr = decode_object(stacktop,start,index);
UNSTACK_TMP(decoded_car);
return EUCALL_2(Fn_cons,decoded_car,decoded_cdr);
case MP_VECTOR :
size = start[(*index)++];
result = allocate_vector(stacktop,size);
for (i=0; i<size; i++) {
LispObject xx;
STACK_TMP(result);
xx=decode_object(stacktop,start,index);
vecrefupdator(result,i,xx);
UNSTACK_TMP(result);
}
return result;
default :
return allocate_integer( stacktop,999 );
}
}
/*----------------------------------------------------------------------------*
* Function : Fn_mp_ref
*
* Parameters : LispObject context: context and offset of
* LispObject offset: Plural we are examining
* LispObject index: Element of plural to examine
*
* Description: Extracts an element from a plural to create a singular front
* end lispobject. This is done by the back end encoding the
* the structure into a character string and this is copied
* to the front end and used to build a replica.
*
* Result : LispObject: Built structure.
*---------------------------------------------------------------------------*/
EUFUN_3( Fn_mp_ref, context, offset, index )
{
DBG_CALL("Error in mp-ref");
LispObject result;
int proc_id;
int xproc_id;
int yproc_id;
int scratch_index = 1;
int transferred;
proc_id=callRequest(mp_plural,24,mp_context_address(context), MP_REF,2,1,
mp_plural_offset(offset),intval(index));
copyIn((char *) &mp_error, &fe_mp_error, sizeof(int));
if (fe_mp_error != MP_GREEN) CallError(stacktop,dbg_fname,allocate_integer(stacktop,fe_mp_error),NONCONTINUABLE);
xproc_id = proc_id % MASPAR_XLEN;
yproc_id = proc_id / MASPAR_XLEN;
transferred = blockIn(pe_scratch,fe_scratch,xproc_id,yproc_id,1,1,
SCRATCH_MEMORY_SIZE);
result = decode_object(stacktop, (char *) fe_scratch, &scratch_index);
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_set
*
* Parameters : LispObject context: Context and offset of the plural
* LispObject offset: we wish to update
* LispObject index: Element we wish to update
* LispObject object: Object to go into element of plural
*
* Description: Recursively descends the object and encodes it into the
* the scratch buffer. This buffer is then read by the back
* end to build a similar object on the appropriate PE.
*
* Result : LispObject plural
*---------------------------------------------------------------------------*/
EUFUN_4( Fn_mp_set, context, offset, index, object )
{
DBG_CALL("Error in mp-set");
fe_data_length = sizeof(int);
/* not gc proof */
encode( stacktop,object ); /* Encode obejct into fe communication space */
memcpy(fe_scratch, (char *) &fe_data_length, sizeof(int));
CallRequest((mp_plural,28,mp_context_address(context), MP_SET, 3, 1,
mp_plural_offset(offset),
intval(index),fe_scratch));
return offset;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_bang
*
* Parameters : LispObject context:
* LispObject object:
*
* Description: Recursively descends the object and encodes it into the
* the scratch buffer. This buffer is then read by the back
* end to build a similar object on all active PEs, i.e. the
* ones in the context
*
* Result : LispObject: offset of new plural
*---------------------------------------------------------------------------*/
EUFUN_2( Fn_mp_bang, context, object )
{
DBG_CALL("Error in mp-bang");
LispObject result;
fe_data_length = sizeof(int);
/* not gc proof */
encode( stacktop, object ); /* Encode obejct into fe communication space */
memcpy(fe_scratch, (char *) &fe_data_length, sizeof(int));
result=allocate_mp_plural(CallRequest((mp_plural, 20,
mp_context_address(context),
MP_BANG, 1, 0,
fe_scratch)));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_assign
*
* Parameters : LispObject context: context of the plurals (we trust)
* LispObject dest: offset of Plural to assign to
* LispObject from: offset Plural to assign from
*
* Description: Copies the contents of the from into dest. The operation is
* sensitive to the current context - this means it can be used
* to combine the results of mp-if and mp-else.
*
* Result : LispObject dest
*---------------------------------------------------------------------------*/
EUFUN_3( Fn_mp_assign, context, dest, from )
{
DBG_CALL("Error in mp-assign");
int result;
result = CallRequest((mp_plural,24,mp_context_address(context), MP_ASSIGN,2,2,
mp_plural_offset(dest),
mp_plural_offset(from)));
return dest;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_cons
*
* Parameters : LispObject context: Context of the two plurals
* LispObject car: Plural to be car of new plural pair
* LispObject cdr: Plural to be cdr of new plural pair
*
* Description: Takes two (conformant) plurals and returns plural of
* their cons.
*
* Result : LispObject cons:
*---------------------------------------------------------------------------*/
EUFUN_3( Fn_mp_cons, context, car, cdr )
{
DBG_CALL("Error in mp-cons");
LispObject pair;
pair = allocate_mp_plural(CallRequest((mp_plural,24,
mp_context_address(context),
MP_MP_CONS,2,2,
mp_plural_offset(car),
mp_plural_offset(cdr))));
return pair;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_car
*
* Parameters : LispObject context: context of pair
* LispObject pair: plural pair to take car of
*
* Description: creates new plural whose value is the car of pair
*
* Result : LispObject NULL - failure, see mp_error
* address of mp_object
*---------------------------------------------------------------------------*/
EUFUN_2( Fn_mp_car, context, pair )
{
DBG_CALL("Error in mp-car");
LispObject car;
car = allocate_mp_plural(CallRequest((mp_plural,20,
mp_context_address(context),MP_CAR,1,1,
mp_plural_offset(pair))));
return car;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_cdr
*
* Parameters : LispObject context: context of pair
* LispObject pair: plural pair to take cdr of
*
* Description: creates new plural whose value is the cdr of pair
*
* Result : LispObject NULL - failure, see mp_error
* address of mp_object
*---------------------------------------------------------------------------*/
EUFUN_2( Fn_mp_cdr, context, pair )
{
DBG_CALL("Error in mp-cdr");
LispObject cdr;
cdr = allocate_mp_plural(CallRequest((mp_plural,20,
mp_context_address(context),MP_CDR,1,1,
mp_plural_offset(pair))));
return cdr;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_rplac_d
*
* Parameters : LispObject context: context of pair and value
* LispObject pair: plural pair to replace cdr of
* LispObject value: plural value to become cdr of pair
*
* Description: Replaces the existing cdr of the pair to be value
*
* Result : LispObject pair - SUCCESS
* NULL - Failure, see mp_error
*---------------------------------------------------------------------------*/
EUFUN_3( Fn_mp_rplac_d, context, pair, value )
{
DBG_CALL("Error in mp-rplac-d");
int result;
result = CallRequest((mp_plural,24,mp_context_address(context),MP_RPLAC_D,2,2,
mp_plural_offset(pair),
mp_plural_offset(value)));
return pair;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_rplac_a
*
* Parameters : LispObject context: Context of pair and value
* LispObject pair: plural pair to replace car of
* LispObject value: plural value to become car of pair
*
* Description: Replaces the existing car of the pair to be value
*
* Result : LispObject pair - SUCCESS
* NULL - Failure, see mp_error
*---------------------------------------------------------------------------*/
EUFUN_3( Fn_mp_rplac_a, context, pair, value )
{
DBG_CALL("Error in mp-rplac-a");
int result;
result = CallRequest((mp_plural,24,mp_context_address(context),MP_RPLAC_A,2,2,
mp_plural_offset(pair),
mp_plural_offset(value)));
return pair;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_make_vector
*
* Parameters : LispObject context: Context of the plural of lengths
* LispObject length: Desrired lengths of the vectors
*
* Description: Allocates vectors of the given lengths and initialises all
* the elements to nil
*
* Result : LispObject: New plural of vectors
*---------------------------------------------------------------------------*/
EUFUN_2( Fn_mp_make_vector, context, length )
{
DBG_CALL("Error in mp-make-vector");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_plural,20,
mp_context_address(context),
MP_MAKE_VECTOR,1,1,
mp_plural_offset(length))));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_vector_length
*
* Parameters : LispObject context: Context of plural of vectors
* LispObject vector: Plural of vectors
*
* Description: Creates a plural in which every active element contains the]
* length of the vector in the argument plural
*
* Result : LispObject lengths
*---------------------------------------------------------------------------*/
EUFUN_2( Fn_mp_vector_length, context, vector )
{
DBG_CALL("Error in mp-vector-length");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_plural,20,
mp_context_address(context),
MP_VECTOR_LENGTH,1,1,
mp_plural_offset(vector))));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_vector_ref
*
* Parameters : LispObject context: Context of vector and index
* LispObject vector: Plural of vectors to reference
* LispObject index: Plural of integers to reference by
*
* Description: Creates a new plural in which the value of each active element
* is the contents of the index th element of each vector
*
* Result : LispObject: referenced objects
*---------------------------------------------------------------------------*/
EUFUN_3( Fn_mp_vector_ref, context, vector, index )
{
DBG_CALL("Error in mp-vector-ref");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_plural,24,
mp_context_address(context),
MP_VECTOR_REF,2,2,
mp_plural_offset(vector),
mp_plural_offset(index))));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_vector_set
*
* Parameters : LispObject context: Context of all the operands
* LispObject vector: Plural of vector to be updated
* LispObject index: PLural of integers indicating elements
* to be updated
* LispObject value: Plural of objects which are to be the
* new value of th indexth element of
* each vector
*
* Description: Updates the indexth element of each active vector to
* be value.
*
* Result : LispObject vector
*---------------------------------------------------------------------------*/
EUFUN_4( Fn_mp_vector_set, context, vector, index, value )
{
DBG_CALL("Error in mp-vector-set");
int result;
result = CallRequest((mp_plural,28,mp_context_address(context),
MP_VECTOR_SET,3,3,
mp_plural_offset(vector),
mp_plural_offset(index),
mp_plural_offset(value)));
return vector;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_vector_merge
*
* Parameters : LispObject context: Context of vector and index
* LispObject vector: Plural of vectors to reference
* LispObject index: Plural of integers to reference by
*
* Description: Creates a new plural in which the value of each active element
* is the contents of the index th element of each vector
*
* Result : LispObject: referenced objects
*---------------------------------------------------------------------------*/
EUFUN_3( Fn_mp_vector_merge, context, set1, set2 )
{
DBG_CALL("Error in mp-vector-merge");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_plural,24,
mp_context_address(context),
MP_VECTOR_MERGE,2,2,
mp_plural_offset(set1),
mp_plural_offset(set2))));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_if
*
* Parameters : LispObject context: Context of the boolean
* LispObject plural_bool: Plural variable to be treated as
* bool - at this time should be
* integers.
*
* Description: This bool will be combined with the value on the
* context stack for this plural to create the new value on
* the context stack. All plurals conformant to this one
* will be affected by this change
*
* Result : LispObject t Some of the processors are active
* nil None of the processors are active
*---------------------------------------------------------------------------*/
EUFUN_2( Fn_mp_if, context, plural_bool )
{
DBG_CALL("Error in mp-if");
int result;
result = CallRequest((mp_plural,20,mp_context_address(context),
MP_IF,1,1,mp_plural_offset(plural_bool)));
if (result == MP_NONE_ACTIVE) return nil;
return lisptrue;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_elif
*
* Parameters : LispObject context: Context of the boolean
*
* Description: Similar to mp-fi, but the preceding context is updated to
* show how many sites have yet to satisfy a predicate in
* a cond expression, the n\behaviour of which is similar to
* a switch statement in mpl.
*
* Result : LispObject t Some of the processors are active
* nil None of the processors are active
*---------------------------------------------------------------------------*/
EUFUN_1( Fn_mp_elif, context )
{
DBG_CALL("Error in mp-elif");
int result;
result = CallRequest((mp_plural,16,mp_context_address(context),
MP_ELIF,0,0));
if (result == MP_NONE_ACTIVE) return nil;
return lisptrue;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_else
*
* Parameters : LispObject context: Context whose stack we are changing
*
* Description: The currenty context is muodified to give the affect that
* the bool given to mp_if had the not of its value. This
* destructively modifies the top of the stack
*
* Result : LispObject plural
*---------------------------------------------------------------------------*/
EUFUN_1( Fn_mp_else, context )
{
DBG_CALL("Error in mp-else");
int result;
result = CallRequest((mp_plural,16,mp_context_address(context),MP_ELSE,0,0));
if (result == MP_NONE_ACTIVE) return nil;
return lisptrue;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_fi
*
* Parameters : LispObject context: Context for which the stack is
* to be popped once.
*
* Description: Removes the top entry from the contect stack for this
* plural. Assuming there is one - error otherwise. This
* will affect all those plurals conformant to this one.
*
* Result : LispObject plural
*---------------------------------------------------------------------------*/
EUFUN_1( Fn_mp_fi, context )
{
DBG_CALL("Error in mp-fi");
int result;
result = CallRequest((mp_plural,16,mp_context_address(context),MP_FI,0,0));
return context;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_context
*
* Parameters : LispObject context: context the stack of which we are
* interested in
*
* Description: Prints out the context of the plural as a plural of lists
*
* Result : LispObject plural
*---------------------------------------------------------------------------*/
EUFUN_1( Fn_mp_context, context )
{
DBG_CALL("Error in mp-context");
int i,transferred;
return allocate_mp_plural( CallRequest((mp_plural,16,mp_context_address(context),MP_CONTEXT,0,0)));
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_and
*
* Parameters : LispObject context: Context of the two operands
* LispObject arg1: Two plurals of lisp thingys to
* LispObject arg2: have a lisp style and done on em.
*
* Description: Preforms an element wise and on the two CONFORMANT plurals
* i.e. NIL has the role of FALSE, anything else is TRUE
*
* Result : LispObject: resulting boolean(ish) plural
*---------------------------------------------------------------------------*/
EUFUN_3( Fn_mp_and, context, arg1, arg2 )
{
DBG_CALL("Error in mp-and");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_plural,24,
mp_context_address(context),
MP_AND,2,2,
mp_plural_offset(arg1),
mp_plural_offset(arg2))));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_or
*
* Parameters : LispObject context: Context of the two operands
* LispObject arg1: Two plurals of lisp thingys to
* LispObject arg2: have a lisp style and done on em.
*
* Description: Preforms an element wise or on the two CONFORMANT plurals
* i.e. NIL has the role of FALSE, anything else is TRUE
*
* Result : LispObject: resulting boolean(ish) plural
*---------------------------------------------------------------------------*/
EUFUN_3( Fn_mp_or, context, arg1, arg2 )
{
DBG_CALL("Error in mp-or");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_plural,24,
mp_context_address(context),
MP_OR,2,2,
mp_plural_offset(arg1),
mp_plural_offset(arg2))));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_not
*
* Parameters : LispObject context: Context of the two operands
* LispObject arg1: Two plurals of lisp thingys to
*
* Description: Preforms an element wise or on the two CONFORMANT plurals
* i.e. NIL has the role of FALSE, anything else is TRUE
*
* Result : LispObject: resulting boolean(ish) plural
*---------------------------------------------------------------------------*/
EUFUN_2( Fn_mp_not, context, arg1 )
{
DBG_CALL("Error in mp-not");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_plural,20,
mp_context_address(context),
MP_NOT,1,1,
mp_plural_offset(arg1))));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_bin_op
*
* Parameters : LispObject context: The context of the operands
* LispObject arg1: Two conformant plurals of integers
* LispObject arg2:
* LispObject op_id: The operation id - an integer
*
* Description: Creates a new plural whose content is the result of
* applying the desired binary operation to the two given plurals
*
* Result : LispObject result
*---------------------------------------------------------------------------*/
EUFUN_4( Fn_mp_bin_op, context, arg1, arg2, op_id )
{
DBG_CALL("Error in mp-bin-op");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_plural, 28,
mp_context_address(context),
MP_BIN_OP, 3, 2,
mp_plural_offset(arg1),
mp_plural_offset(arg2),
intval(op_id))));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_rel_op
*
* Parameters : LispObject context: The context of the operands
* LispObject arg1: Two conformant plurals of integers
* LispObject arg2:
* LispObject op_id: The operation id - an integer
*
* Description: Creates a new plural whose content is the result of
* applying the desired relary operation to the two given plurals
*
* Result : LispObject result
*---------------------------------------------------------------------------*/
EUFUN_4( Fn_mp_rel_op, context, arg1, arg2, op_id )
{
DBG_CALL("Error in mp-rel-op");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_plural, 28,
mp_context_address(context),
MP_REL_OP, 3, 2,
mp_plural_offset(arg1),
mp_plural_offset(arg2),
intval(op_id))));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_un_op
*
* Parameters : LispObject context: The context of the operand
* LispObject arg: Plural of ints and/or floats
* LispObject op_id: The operation id - an integer
*
* Description: Creates a new plural whose content is the result of
* applying the desired unary operation to the given plural
*
* Result : LispObject result
*---------------------------------------------------------------------------*/
EUFUN_3( Fn_mp_un_op, context, arg, op_id )
{
DBG_CALL("Error in mp-un-op");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_plural, 24,
mp_context_address(context),
MP_UN_OP, 2, 1,
mp_plural_offset(arg),
intval(op_id))));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_scan_op
*
* Parameters : LispObject context: The context of the operand
* LispObject arg: Plural of ints and/or floats
* LispObject op_id: The operation id - an integer
*
* Description: Creates a new plural whose content is the result of
* applying the desired scan operation to the given plural
*
* Result : LispObject result
*---------------------------------------------------------------------------*/
EUFUN_3( Fn_mp_scan_op, context, arg, op_id )
{
DBG_CALL("Error in mp-scan-op");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_plural, 24,
mp_context_address(context),
MP_SCAN_OP, 2, 1,
mp_plural_offset(arg),
intval(op_id))));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_random
*
* Parameters : LispObject context: The context of the operand
*
* Description: Creates a new plural with a random integer in each element
*
* Result : LispObject result: the offset of the resullting plural
*---------------------------------------------------------------------------*/
EUFUN_1( Fn_mp_random, context )
{
DBG_CALL("Error in mp-random");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_plural, 16,
mp_context_address(context),
MP_RANDOM, 0, 0)));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_test
*
* Parameters : LispObject context: Context of the operands
* LispObject arg1: Things we are testing
* LispObject type: Things we hope the things are
*
* Description: Returns a boolean plural dependfing on wether the things
* were the things or not.
*
* Result : LispObject: The resulting boolean
*---------------------------------------------------------------------------*/
EUFUN_3( Fn_mp_test, context, arg1, type )
{
DBG_CALL("Error in mp-test");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_plural, 24,
mp_context_address(context),
MP_TEST, 2, 1,
mp_plural_offset(arg1),
intval(type))));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_eq
*
* Parameters : LispObject context: Context of the operands
* LispObject arg1: The two plurals which are to be
* LispObject arg2: compared.
*
* Description: Returns a boolean plural dependent on wether the individual
* elements are equal. By value for floats and ints, by address
* for everything else.
*
* Result : LispObject: The resulting boolean plural
*---------------------------------------------------------------------------*/
EUFUN_3( Fn_mp_eq, context, arg1, arg2 )
{
DBG_CALL("Error in mp-eq");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_plural,24,
mp_context_address(context),
MP_EQ,2,2,
mp_plural_offset(arg1),
mp_plural_offset(arg2))));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_length
*
* Parameters : LispObject context: context to find length of.
*
* Description: Extracts the length of the plural from its handle on the
* back end.
*
* Result : LispObject: INT->value = plural-length
*---------------------------------------------------------------------------*/
EUFUN_1( Fn_mp_length, context )
{
DBG_CALL("Error in mp-length");
int n;
/* n = callRequest(mp_length,4,mp_context_address(context));
return allocate_integer(stacktop,n); */
return nil;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_match
*
* Parameters : LispObject dest_context:Contex of destination plural
* LispObject dest: Offset of destination plural
* LispObject from_context:Contex of source plural
* LispObject from: Offset of Source plural
*
* Description: Builds a mapping plural - each element contains a list of
* processor ids - this is where each element will take
* data from to build a plural conformant to the destination
* plural - or something
*
* Result : LispObject Fn_mp_match
*---------------------------------------------------------------------------*/
EUFUN_4( Fn_mp_match, dest_contex, dest, from_contex, from )
{
DBG_CALL("Error in mp-match");
LispObject mapping;
mapping = allocate_mp_plural(CallRequest((mp_match,16,
mp_context_address(dest_contex),
mp_plural_offset(dest),
mp_context_address(from_contex),
mp_plural_offset(from))));
return mapping;
}
EUFUN_CLOSE
EUFUN_5( Fn_mp_move, context, data, map_context, map, initial_value )
{
DBG_CALL("Error in mp-move");
LispObject result;
result = allocate_mp_plural(CallRequest((mp_move,20,
mp_context_address(context),
mp_plural_offset(data),
mp_context_address(map_context),
mp_plural_offset(map),
mp_plural_offset(initial_value))));
return result;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_cm_put
*
* Parameters : LispObject data_context: context of data to put
* LispObject data_offset: offset of data to put
* LispObject dest_offset: which procs to put to
* LispObject context: context of result plural
*
* Description: Creates a new plural with context context, which contains
* the objects in the data plural moved into it as specified
* by the destination plural. this operation requires no
* matching and should make things quicker
*
* Result : LispObject offset: together with context => result plural
*---------------------------------------------------------------------------*/
EUFUN_4(Fn_cm_put, data_context, data_offset, dest_offset, context )
{
DBG_CALL("Error in cm-put");
int result;
result = CallRequest((cm_put,16,
mp_context_address(data_context),
mp_plural_offset(data_offset),
mp_plural_offset(dest_offset),
mp_context_address(context)));
return allocate_mp_plural(result);
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_cm_start
*
* Parameters : LispObject context: context of data to put
*
* Description: returns the number of the PE the context starts at. This will
* allow to further inverse rendezvous without matching
*
* Result : LispObject start: the PE number
*---------------------------------------------------------------------------*/
EUFUN_1( Fn_cm_start, context )
{
DBG_CALL("Error in cm-start");
int n;
n=callRequest(cm_start,4,mp_context_address(context));
return allocate_integer(stacktop,n);
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_x_stat
*
* Parameters : LispObject context: Context of the boolean data
* LuspObject bool_data: Offsets of the data
*
* Description: The call to the backend sets a boolean value in each PE
* this is then copied back and used as the argument to xlights
*
* Result : LispObject: the arg
*---------------------------------------------------------------------------*/
EUFUN_2( Fn_mp_x_stat, context, bool_data )
{
DBG_CALL("Error in mp-x-stat");
int transferred;
int value;
char c_value;
int i,j;
CallRequest((mp_plural, 20, mp_context_address(context), MP_X_STAT, 1, 1,
mp_plural_offset(bool_data)));
transferred = blockIn(pe_scratch,fe_scratch,0,0,MASPAR_XLEN,
MASPAR_YLEN, 1);
#ifdef XLIGHTS
visualise(fe_scratch);
#else
printf("\n");
for (i=0; i<MASPAR_YLEN; i++) {
for (j=0; j<MASPAR_XLEN; j++) {
c_value = * (((char *) (fe_scratch)) + (i*MASPAR_XLEN) + j);
value = c_value;
printf(" %d", value);
}
printf("\n");
}
printf("\n");
#endif
return bool_data;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_gc
*
* Parameters : void
*
* Description: This is a temporary devlopment function to fire a GC process
* on the back end. It prints out memory stats at completion.
*
* Result : LispObjectt: ()
*---------------------------------------------------------------------------*/
EUFUN_0( Fn_mp_gc)
{
DBG_CALL("Error in mp-gc");
int transferred;
int value;
int x,y;
callRequest(mp_gc, 0);
transferred = blockIn(pe_scratch, fe_scratch,0 ,0, MASPAR_XLEN,
MASPAR_YLEN, sizeof(float));
/* printf("MasPar memory statistics:\n");
*
* for(y=0; y<MASPAR_YLEN; y++) {
* for(x=0; x<MASPAR_XLEN; x++) {
* value = *(((int *) fe_scratch) + (y*MASPAR_YLEN) + x);
* if (value > 9) printf(" %d",value);
* else printf(" 0%d", value);
* }
* printf("\n");
* }
* printf("\n\n");
*/
return nil;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_become_strange
*
* Parameters : LispObject normal: to become strange
*
* Description: Marks the objects as being strange, i.e. a handle on a
* back-end object. This function should be called by all
* creator functions.
*
* Result : LispObject: The now strange object
*---------------------------------------------------------------------------*/
EUFUN_1( Fn_become_strange, normal )
{
lval_typeof(normal)=TYPE_STRANGE;
return normal;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : keep_strange_things
*
* Parameters : LispObject strange_things
*
* Description: Creates a compact (i.e. not made out out of cons celss version
* version of the list which can then be paged onto the MasPar
* so that they can be marked as still being used and the
* remainder reclaimed.
* PROB: if we run out of front end stack space we will "err".
* "So it goes!"
* SOLN: clear plurals space is a seperate to freeplurals
*
* Result : LispObject :Number of active plurals
*---------------------------------------------------------------------------*/
#ifdef __STDC__
void keep_strange_things( LispObject strange_list )
#else
void keep_strange_things( strange_list )
LispObject strange_list;
#endif
{
unsigned short *pages = (unsigned short *) fe_scratch;
LispObject strange_current;
LispObject list_current;
int no_of_plurals = 0;
LispObject strange_ctxt, strange_ofst;
LispObject current_ctxt, current_ofst;
LispObject mapping_ofst;
if (strange_list == 0) {
if (callRequest(mp_free_plurals,8,fe_scratch,no_of_plurals) == FAIL)
fprintf(stderr,"Major bummer during GC of plural handles\n");
fprintf(stderr,"No Plural Handles\n");
return;
}
while (TRUE) {
strange_current = CAR(strange_list);
current_ctxt = slotref(strange_current,0);
current_ofst = slotref(strange_current,1);
if (is_cons(current_ofst)) { /* must be a field */
current_ctxt = slotref(current_ctxt,0); /* contexts list in paralation */
while (is_cons(current_ctxt)) {
strange_ctxt = CAR(current_ctxt);
current_ctxt = CDR(current_ctxt);
strange_ofst = CAR(current_ofst);
if (is_cons(strange_ofst)) {
while (is_cons(strange_ofst)) {
mapping_ofst = CAR(strange_ofst);
strange_ofst = CDR(strange_ofst);
*(pages++) = (unsigned short) intval(strange_ctxt);
*(pages++) = (unsigned short) intval(mapping_ofst);
fprintf(stderr,"context(16-bit): %hu offset(16-bit): %hu 32-bits %08x\n",
*(pages-2), *(pages-1), *((unsigned *) (pages-2)));
no_of_plurals++;
}
}
else {
current_ofst = CDR(current_ofst);
*(pages++) = (unsigned short) intval(strange_ctxt);
*(pages++) = (unsigned short) intval(strange_ofst);
fprintf(stderr,"context(16-bit): %hu offset(16-bit): %hu 32-bits %08x\n",
*(pages-2), *(pages-1), *((unsigned *) (pages-2)));
no_of_plurals++;
}
}
}
else {
*(pages++) = (unsigned short) intval(current_ctxt);
*(pages++) = (unsigned short) intval(current_ofst);
fprintf(stderr,"context(16-bit): %hu offset(16-bit): %hu 32-bits %08x\n",
*(pages-2), *(pages-1), *((unsigned *) (pages-2)));
no_of_plurals++;
}
if (CDR(strange_list) == strange_list) break;
strange_list = CDR(strange_list);
}
if (callRequest(mp_free_plurals,8,fe_scratch,no_of_plurals) == FAIL)
fprintf(stderr,"Major bummer during garbage collect of plural handles\n");
fprintf(stderr,"%d active plurals\n",no_of_plurals);
}
/*----------------------------------------------------------------------------*
* Function : Fn_ps_ref
*
* Parameters : none
*
* Description: Returns value of plural space to the lisp environment
*
* Result : LispObject pspace intgeger.
*---------------------------------------------------------------------------*/
EUFUN_0(Fn_ps_ref)
{
DBG_CALL("Error in ps-ref");
unsigned short tmp;
copyIn((char *) &plural_space,(char *) &tmp, sizeof(unsigned short));
return allocate_integer(stacktop, (int) tmp);
}
EUFUN_CLOSE
EUFUN_1(Fn_ps_set,new_value)
{
DBG_CALL("Error in ps-set");
unsigned short tmp = (unsigned short) intval(new_value);
copyOut( (char *) &tmp, (char *) &plural_space, sizeof(unsigned short));
return(new_value);
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_sb_ref
*
* Parameters : none
*
* Description: Returns value of stack base to the lisp environment
*
* Result : LispObject pspace intgeger.
*---------------------------------------------------------------------------*/
EUFUN_0(Fn_sb_ref)
{
DBG_CALL("Error in sb-ref");
unsigned short tmp;
copyIn((char *) &stack_base,(char *) &tmp, sizeof(unsigned short));
return allocate_integer(stacktop, (int) tmp);
}
EUFUN_CLOSE
EUFUN_1(Fn_sb_set,new_value)
{
DBG_CALL("Error in sb-set");
unsigned short tmp = (unsigned short) intval(new_value);
copyOut( (char *) &tmp, (char *) &stack_base, sizeof(unsigned short));
return(new_value);
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_config
*
* Parameters : none
*
* Description: Returns maspar lisp configuration
*
* Result : LispObject pspace intgeger.
*---------------------------------------------------------------------------*/
EUFUN_0(Fn_mp_config)
{
DBG_CALL("Error in mp-config");
return allocate_integer(stacktop, (maspar_config/2));
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_dbg_on
*
* Parameters : none
*
* Description: Returns maspar lisp configuration
*
* Result : LispObject pspace intgeger.
*---------------------------------------------------------------------------*/
extern int debug_status;
EUFUN_0(Fn_dbg_on)
{
DBG_CALL("Error in dbg-on");
int tmp = 1;
copyOut( (char *) &tmp, (char *) &debug_status, sizeof(int));
return(lisptrue);
}
EUFUN_CLOSE
EUFUN_0(Fn_dbg_off)
{
int tmp = 0;
DBG_CALL("Error in dbg-on");
fprintf(stderr,"We are now in Fn_dbg_on\n");
copyOut( (char *) &tmp, (char *) &debug_status, sizeof(int));
return(lisptrue);
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_mp_edge
*
* Parameters : LispObject context: The context whose contexts stacks
* are to be munged
* LispObject direction: The edge we want to be active
*
* Description: Like mp-if, makes one edge of a rectangular context active
*
* Result : LispObject nil - no active elements
* t - some active elements
*---------------------------------------------------------------------------*/
EUFUN_2(Fn_mp_edge, context, direction)
{
int result;
DBG_CALL("Error in mp_edge");
fprintf(stderr,"We are now in Fn_mp_edge\n");
result = CallRequest((mp_edge,8,mp_context_address(context),
intval(direction)));
if (result == MP_SOME_ACTIVE) return lisptrue;
return nil;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : Fn_xnet
*
* Parameters : LispObject context: Context which all the data is in
* LispObject direction: Where to get data from
* LispObject offsets: List of offsets (in order)
*
* Description: Extracts all the offsets and writes them into the scratch
* space so that they can be block copied into the ACU and
* dealt with there by mp_xnet
* This is a destructive operation
*
* Result : LispObject lisptrue/nil FAIL/SUCCESS
*---------------------------------------------------------------------------*/
EUFUN_3( Fn_xnet, contexts , offsets, direction )
{
LispObject current_ctxt_pair = contexts;
LispObject current_ofst_pair = offsets;
LispObject offset;
LispObject context;
int i = 0;
unsigned short *pages = (unsigned short *) fe_scratch;
DBG_CALL("Error in mp-xnet");
while (is_cons(current_ctxt_pair)) {
context = CAR(current_ctxt_pair);
current_ctxt_pair = CDR(current_ctxt_pair);
pages[i++] = (unsigned short) intval(context);
offset = CAR(current_ofst_pair);
current_ofst_pair = CDR(current_ofst_pair);
pages[i++] = (unsigned short) intval(offset);
}
i = i/2;
CallRequest((mp_xnet,12,intval(direction),i,fe_scratch));
return lisptrue;
}
EUFUN_CLOSE
/*----------------------------------------------------------------------------*
* Function : INIT_plural
*
* Parameters : void:
*
* Description: Initialises Plural Module
*
* Result : void:
*---------------------------------------------------------------------------*/
#define PLURAL_ENTRIES (49)
MODULE Module_plural;
LispObject Module_plural_values[PLURAL_ENTRIES];
#ifdef __STDC__
void INIT_plural(LispObject *stacktop)
#else
void INIT_plural(stacktop)
LispObject *stacktop;
#endif
{
DBG_CALL("Error in INIT_plural");
open_module(stacktop,&Module_plural,Module_plural_values,"plural",PLURAL_ENTRIES);
(void) make_module_function(stacktop,"mp-make-context",Fn_mp_make_context,2);
(void) make_module_function(stacktop,"mp-make-plural",Fn_mp_make_plural,1);
(void) make_module_function(stacktop,"mp-print",Fn_mp_print,5);
(void) make_module_function(stacktop,"mp-set",Fn_mp_set,4);
(void) make_module_function(stacktop,"mp-ref",Fn_mp_ref,3);
(void) make_module_function(stacktop,"mp-bang",Fn_mp_bang,2);
(void) make_module_function(stacktop,"mp-cons",Fn_mp_cons,3);
(void) make_module_function(stacktop,"mp-car",Fn_mp_car,2);
(void) make_module_function(stacktop,"mp-cdr",Fn_mp_cdr,2);
(void) make_module_function(stacktop,"mp-rplac-a",Fn_mp_rplac_a,3);
(void) make_module_function(stacktop,"mp-rplac-d",Fn_mp_rplac_d,3);
(void) make_module_function(stacktop,"mp-if",Fn_mp_if,2);
(void) make_module_function(stacktop,"mp-else",Fn_mp_else,1);
(void) make_module_function(stacktop,"mp-file",Fn_mp_elif,1);
(void) make_module_function(stacktop,"mp-fi",Fn_mp_fi,1);
(void) make_module_function(stacktop,"mp-context",Fn_mp_context,1);
(void) make_module_function(stacktop,"mp-and",Fn_mp_and,3);
(void) make_module_function(stacktop,"mp-or",Fn_mp_or,3);
(void) make_module_function(stacktop,"mp-not",Fn_mp_not,2);
(void) make_module_function(stacktop,"mp-assign",Fn_mp_assign,3);
(void) make_module_function(stacktop,"mp-bin-op",Fn_mp_bin_op,4);
(void) make_module_function(stacktop,"mp-rel-op",Fn_mp_rel_op,4);
(void) make_module_function(stacktop,"mp-un-op",Fn_mp_un_op,3);
(void) make_module_function(stacktop,"mp-scan-op",Fn_mp_scan_op,3);
(void) make_module_function(stacktop,"mp-random",Fn_mp_random,1);
(void) make_module_function(stacktop,"mp-test",Fn_mp_test,3);
(void) make_module_function(stacktop,"mp-eq",Fn_mp_eq,3);
(void) make_module_function(stacktop,"mp-length",Fn_mp_length,1);
(void) make_module_function(stacktop,"mp-make-vector",Fn_mp_make_vector,2);
(void) make_module_function(stacktop,"mp-vector-length",Fn_mp_vector_length,2);
(void) make_module_function(stacktop,"mp-vector-ref",Fn_mp_vector_ref,3);
(void) make_module_function(stacktop,"mp-vector-set",Fn_mp_vector_set,4);
(void) make_module_function(stacktop,"mp-vector-merge",Fn_mp_vector_merge,3);
(void) make_module_function(stacktop,"mp-move",Fn_mp_move,5);
(void) make_module_function(stacktop,"mp-match",Fn_mp_match,4);
(void) make_module_function(stacktop,"cm-put",Fn_cm_put,4);
(void) make_module_function(stacktop,"cm-start",Fn_cm_start,1);
(void) make_module_function(stacktop,"mp-x-stat",Fn_mp_x_stat,2);
(void) make_module_function(stacktop,"mp-gc", Fn_mp_gc, 0);
(void) make_module_function(stacktop,"become-strange", Fn_become_strange, 1);
(void) make_module_function(stacktop,"mp-ps-ref", Fn_ps_ref, 0);
(void) make_module_function(stacktop,"mp-ps-set", Fn_ps_set, 1);
(void) make_module_function(stacktop,"mp-sb-ref", Fn_sb_ref, 0);
(void) make_module_function(stacktop,"mp-sb-set", Fn_sb_set, 1);
(void) make_module_function(stacktop,"mp-config", Fn_mp_config, 0);
(void) make_module_function(stacktop,"mp-dbg-on", Fn_dbg_on, 0);
(void) make_module_function(stacktop,"mp-dbg-off", Fn_dbg_off, 0);
(void) make_module_function(stacktop,"mp-xnet", Fn_xnet, 3);
(void) make_module_function(stacktop,"mp-edge",Fn_mp_edge, 2);
fe_symbol_table = EUCALL_1(Fn_make_table,nil);
reffed_symbols = EUCALL_1(Fn_make_table,nil);
add_root(&fe_symbol_table);
add_root(&reffed_symbols);
TREF_UPDATE(fe_symbol_table,allocate_integer(stacktop,MP_NIL_ID),nil);
TREF_UPDATE(reffed_symbols,nil,allocate_integer(stacktop,MP_NIL_ID));
TREF_UPDATE(fe_symbol_table,allocate_integer(stacktop,MP_T_ID),lisptrue);
TREF_UPDATE(reffed_symbols,lisptrue,allocate_integer(stacktop,MP_T_ID));
next_symbol_key = 2;
ListOfStrangeThings = 0;
pe_scratch = (char *) CallRequest((mp_init_plural,0));
copyIn( (char *) &private_nproc, (char *) &maspar_config, sizeof(int));
fprintf(stderr,"\nMasPar Configuration = %d\n", maspar_config);
fe_scratch = malloc(maspar_config*SCRATCH_MEMORY_SIZE);
close_module();
}